/*************************************************************************
 *
 *   file		: StealBeneficialBuff.cs
 *   copyright		: (C) The WCell Team
 *   email		: info@wcell.org
 *   last changed	: $LastChangedDate: 2009-06-29 12:21:28 +0100 (Mon, 29 Jun 2009) $
 *   last author	: $LastChangedBy: dominikseifert $
 *   revision		: $Rev: 1041 $
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *************************************************************************/

using System;
using System.Collections.Generic;
using WCell.Constants;
using WCell.Constants.Spells;
using WCell.RealmServer.Entities;
using WCell.RealmServer.Spells.Auras;

namespace WCell.RealmServer.Spells.Effects
{
	/// <summary>
	/// Steals a positive Aura -which has a timeout and is not channeled- off the target and applies it on oneself
	/// </summary>
	public class StealBeneficialBuffEffectHandler : SpellEffectHandler
	{
		List<Aura> m_toSteal;

		public StealBeneficialBuffEffectHandler(SpellCast cast, SpellEffect effect)
			: base(cast, effect)
		{
		}

		public override SpellFailedReason CheckValidTarget(WorldObject target)
		{
			foreach (var aura in ((Unit)target).Auras)
			{
				// find a stealable positive auras
				if (aura.IsBeneficial && aura.CanBeStolen && aura.TimeLeft > 100)
				{
					if (m_toSteal == null)
						m_toSteal = new List<Aura>(5);
					m_toSteal.Add(aura);
					return SpellFailedReason.Ok;
				}
			}

			return SpellFailedReason.NothingToSteal;
		}

		// TODO: Make sure that if multiple casters steal from the same target at the same time,
		// that they don't just move around one buff between each other?
		protected override void Apply(WorldObject target)
		{
			var cast = m_cast;
			if (m_toSteal != null && cast != null)
			{
				foreach (var toSteal in m_toSteal)
				{
					var auras = toSteal.Auras;
					if (auras != null)
					{
						var owner = auras.Owner;
						if (owner != null)
						{
							// remove from owner
							toSteal.Remove(true);

							// apply to caster
							var casterAuras = cast.CasterUnit.Auras;
							if (casterAuras != null)
							{
								casterAuras.Add(toSteal);
							}

							// maximum 2 minutes or the spell's duration
							var maxDur = Math.Min(Effect.Spell.GetDuration(cast.Caster.CasterInfo, null), 2000 * 60);
							if (toSteal.TimeLeft > maxDur)
							{
								toSteal.TimeLeft = maxDur;
							}
							AuraHandler.SendAuraUpdate(cast.CasterUnit, toSteal);
						}
					}
				}
			}
		}

		public override ObjectTypes TargetType
		{
			get
			{
				return ObjectTypes.Unit;
			}
		}

		public override ObjectTypes CasterType
		{
			get
			{
				return ObjectTypes.Unit;
			}
		}
	}
}
